This is a common occurrence even in standard
programming, there are cases where it is diffcult to
express data using only single-typed, regularly aligned
array. There are cases where we need to include
different-typed values, or include arrays of different
shapes.
To address these needs, AROAPL supports “tuple
structure”.
From the perspective of general languages, it can be
seen as anonymous structures.
On the other hand, from the perspective of APL, it
serves as an alternative to “nested array”.
In this point, I’ll focus on the latter
perspective.
To begin with, in APL, array can include anything, even
different-typed values, even primitive single type
values and nested arrays, even different-structured
nested arrays.
The biggest problem is arrays become chaostic black box.
If you get shape with ρ monad, you can
never understand truly what they actually are.
In AROAPL, I provide consistency in type of array in
order to understand and control easily for both
compilers and programmers.
A single array can contain only one type, including
arrayed tuple structures, too.
I don’t necessarily see the name “tuple structure” as a way to specifically differentiate it from “nested arrays,” but as a fundamental design principle of AROAPL, I feel that the term “nested array” itself is inappropriate. Still “tuple structure” is better than it.
Tuple structures are often used in user-defined
functions or system outputs. For more practical
examples, we’ll learn later.
Also, there are some cases where it is impossible of
type inference in tuple structures. In such cases, we
have to define type with variable. This will be covered
in chapter 10. In this section, I’ll introduce
combination and some primitive system functions.
5.1. Combination in Tuple Structures
We use & (combination) dyad
method.
The definition and combination of tuple structures are
below:
A: ⟨β⟩ ← ⟨⊤⟩;
B: ⟨κ[?]⟩ ← ⟨"HELLO WORLD"⟩;
C: ⟨β, κ[?]⟩ ← A & B;
⎕ ← C;
⟨⊤, "HELLO WORLD"⟩;
Even if both are the same type, you have to wrap with
⟨ ⟩ delimiters, because it becomes an
combined array:
A ← 8;
B ← ¯5;
C ← A & B;
⎕ ← C;
8 ¯5
To fix it, like this:
A ← ⟨8⟩;
B ← ⟨¯5⟩;
C ← A & B;
⎕ ← C;
⟨8, ¯5⟩
If you want to combine ⟨8⟩ and
⟨⊤, "HELLO WORLD"⟩ as
⟨8, ⟨⊤, "HELLO WORLD"⟩⟩, you should define
like this:
A ← ⟨8⟩;
B ← ⟨⊤, "HELLO WORLD"⟩;
⎕ ← A & B; ⍝ WRONG WAY ⍝
⎕ ← A & ⟨B⟩; ⍝ CORRECT WAY ⍝
⟨8, ⊤, "HELLO WORLD"⟩
⟨8, ⟨⊤, "HELLO WORLD"⟩⟩
Or, like this:
⎕ ← ⟨8⟩ & ⟨⟨⊤, "HELLO WORLD"⟩⟩;
⟨8, ⟨⊤, "HELLO WORLD"⟩⟩
5.2. Conditional Expression Functions
At this point, you’re probably excited, thinking,
“Finally, we’ve reached the if statement! Conditional
branching!”.
However, I have some slightly disappointing news.
Conditional “branching” is impossible, because it is
conditional “expression”.
So, you cannot branch into separate code blocks like the
if statement.
AROAPL supports “if function” and “switch
function”.
I’ll explain why in chapter 12.
5.2.1. IF Function
When we want to return different values depending on
a condition, we can use the ⎕IF system
monad function.
Here, we’ll encounter a new syntax for the first time.
If function is followed by a type.
This is called “generic type”. For functions where this
is specified, you have to provide a type definition. And
we can only declare one.
Here is an example where the SINC formula is very effective:
RAD ← ⎕:φ;
SINC ← IF:κ[?] ⟨RAD = 0., 1., (⎕SIN ω) ÷ ω⟩;
⎕ ← SINC;
INPUT(φ): 0
1.
INPUT(φ): 1.69
0.5875169533101293
5.2.2. Switch Function
And ⎕SWITCH system monad function that
is the extension of the ⎕IF function is
supported including an generic type, too.
Unlike in most languages, there are no bound variables
in conditional expressions. However, if multiple
conditions evaluate to true, the first one encountered
takes precedence and is returned as the result.
i: ← 1;
⎕ ← SW:κ[?] ⟨⟨i = 0, "FISH"⟩ ⟨i = 1, "BEEF"⟩ ⟨i = 2, "CHICKEN"⟩, "PORK"⟩;
BEEF
And if none of the conditions match, a default value is returned.
i: ← -2;
⎕ ← SW:κ[?] ⟨⟨i = 0, "FISH"⟩ ⟨i = 1, "BEEF"⟩ ⟨i = 2, "CHICKEN"⟩, "PORK"⟩;
PORK